<template>
  <div class="table-wrapper" ref="tableWrapper">
    <div class="table-header" v-if="showHeader" ref="tableHeader">
      <div v-for="col in tableColumns" :key="col.name" :style="{ width: col.width ? col.width + 'px' : null, flex: col.width ? null : 1 }" class="table-header-item">
        {{ col.label }}
      </div>
    </div>

    <div class="table-content">
      <splide class="full-height" :options="options" ref="scrollTable">
        <splide-slide v-for="(row, idx) in data" :key="idx">
          <div class="table-row" :class="{ stripe: idx % 2 === 1 }">
            <div v-for="col in tableColumns" :key="col.name" @click="handleCellClick(row, col.name, idx)" class="cell-item" :style="{ width: col.width ? col.width + 'px' : null, flex: col.width ? null : 1 }">
              <div v-if="col.name === '_index'" class="index-item">
                <div class="index">{{ row['_index'] || idx + 1 }}</div>
              </div>
              <div v-else class="ceil" :style="{ 'text-align': col.align }" :class="typeof col.class === 'function' ? col.class(row) : col.class">
                <slot :name="`col-${col.name}`" v-bind="row">
                  {{ typeof col.format === 'function' ? col.format(row[col.name], row) : row[col.name] }}
                </slot>
              </div>
            </div>
          </div>
        </splide-slide>
      </splide>
    </div>
  </div>
</template>

<script>
import { defineComponent, ref } from 'vue';
import { Splide, SplideSlide } from '@splidejs/vue-splide';
import '@splidejs/splide/css';

export default defineComponent({
  name: 'scrollTable',
  components: {
    Splide,
    SplideSlide
  },
  props: {
    // 传入的表格数据
    data: {
      type: Array,
      default: () => []
    },
    // 列定义 { name: 'sort_index', label: '编号', width: 100 / ratio, align: 'center' },
    columns: {
      type: Array,
      default: () => []
    },
    // 是否展示表格头
    showHeader: {
      type: Boolean,
      default: true
    },
    // 是否展示行号
    showIndex: {
      type: Boolean,
      default: true
    },
    // 显示几行数据
    rowCount: {
      type: Number,
      default: 8
    }
  },
  data () {
    return {
      options: {
        rewind: true, // 回放
        direction: 'ttb', // 滚动方向，ttb-Top to bottom, ltr-Left to right, rtl-Right to left
        height: '356px', // 转盘高度
        wheel: true, // 启用鼠标滚轮导航
        perPage: 8, // 幻灯片数量
        perMove: 1, // 移动的幻灯片数量
        arrows: false, // 是否创建箭头
        pagination: false, // 是否创建分页（指示点）。
        autoplay: true, // 自动播放
        interval: 3000 // 自动播放间隔
      }
    };
  },
  mounted () {
    this.calcSize();
    this.observeResize();

    setTimeout(() => { // 刚载完，貌似不会轮播，手工触发一下
      this.$refs.scrollTable.splide.Components.Autoplay.play();
    }, 500);
  },
  beforeUnmount () {
    this.unobserveResize();
  },
  methods: {
    // 观察尺寸变动
    observeResize () {
      const target = this.$refs.tableWrapper;
      this.resizeObserver = new ResizeObserver(entries => {
        // const entry = entries[0];
        // this.currentWidth = entry.contentRect.width;
        // this.currentHeight = entry.contentRect.height;
        this.calcSize();
      });
      this.resizeObserver.observe(target);
    },
    // 取消观察
    unobserveResize () {
      if (this.resizeObserver) {
        this.resizeObserver.disconnect();
      }
    },
    calcSize () {
      // 计算标题行高
      const headerHeight = this.$refs.tableHeader ? this.$refs.tableHeader.clientHeight : 0;

      // 计算表格区域高度
      this.options.height = `${this.$refs.tableWrapper.clientHeight - headerHeight}px`;
      this.options.perPage = this.rowCount;
    },
    // 点击触发
    handleCellClick (row, col, index) {
      this.$emit('change', { row, col, index });
    },
    // 数据行高
    dataRowHeight (row) {
      const contentHeight = this.$refs.tableWrapper.clientHeight - this.headerHeight;
      const rowHeight = `${contentHeight / this.rowCount}`;
      const height = `${rowHeight}px`;

      return height;
    }
  },
  computed: {
    tableColumns () {
      const cols = [...this.columns];
      if (this.showIndex) {
        cols.unshift({
          name: '_index',
          label: '#',
          width: 80,
          align: 'center'
        });
      }

      return cols;
    }
  },
  watch: {
    rowCount (val) {
      this.options.perPage = val;
    }
  }
});
</script>

<style lang="scss" scoped>
.table-wrapper {
  width: 100%;
  height: 100%;
  span {
    box-sizing: border-box;
  }
  .table-header {
    width: 100%;
    display: flex;
    flex-direction: row;
    div {
      color: #FFFFFF; // rgba(131, 194, 238, 1);
      background-color: rgb(25, 129, 246); // #013558;
      font-size: 22px;
      font-weight: 500;
      // line-height: 36px;
      &:nth-child(2) {
        text-align: center;
      }
    }
    div + div {
      margin-left: 1px;
    }
    .table-header-item {
      text-align: center;
      padding: 0 10px;
      box-sizing: border-box;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      transition: all 0.3s;
    }
  }

  .table-content {
    width: 100%;
    height: 284px;
    margin-top: 1px;

    .table-row {
      width: 100%;
      // cursor: pointer;
      display: flex;
      flex-direction: row;
      height: 100%;
      background: rgba(10, 29, 50, 0.8);

      &.stripe {
        background: rgba(0, 44, 81, 0.8);
      }

      div + div {
        margin-left: 1px;
      }

      .cell-item {
        display: flex;
        flex-wrap: nowrap;
        align-items: center;

        font-size: 22px;
        font-weight: 400;

        .ceil {
          padding: 0 10px;
          box-sizing: border-box;
          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;
          width: 100%;
        }

        .index-item {
          width: 100%;
          display: flex;
          justify-content: center;
        }

        .index {
          background-color: #1981f6;
          border-radius: 3px;
          padding: 0px 3px;
        }
      }
    }
  }
}

</style>
